#include "Enemy.h"
#include "../Game.h"
#include "../DestroyEntityMsg.h"

#include "../Player.h"
#include "../CreateBulletMessage.h"

CEnemy::CEnemy(void)
{

}


CEnemy::~CEnemy(void)
{

}

void CEnemy::Update(float fElapsedTime)
{
	if(this->m_nHealth <= 0)
	{
		CDestroyEntityMsg* pMsg = new CDestroyEntityMsg(this);
		CMessageSystem::GetInstance()->SendMsg(pMsg);
		pMsg = nullptr;
	}
	CEntity::Update(fElapsedTime);

	m_pAM=CAnimationManager::GetInstance();
	m_pAM->Update(fElapsedTime,this->m_cAniInfo);
	//Get current animations
	this->SetHeight(m_pAM->GetCHeight(m_cAniInfo));
	this->SetWidth(m_pAM->GetCWidth(m_cAniInfo));


	if(this->GetPosY() + this->GetHeight() < CGame::GetInstance()->GetHeight() && this->OnPlatform() == false)
		this->SetVelY(this->GetVelY()+1);
	if(this->GetPosY() + this->GetHeight() > (int)CGame::GetInstance()->GetHeight())
		this->SetPosY((float)CGame::GetInstance()->GetHeight()-this->GetHeight());
	if(this->GetPosX() <= 0)
		if(this->GetVelX() < 0)
		{
			this->SetVelX(0);
			this->SetPosX(0);
		}
		if(this->GetPosX() + this->GetWidth() >= CGame::GetInstance()->GetWidth())
			if(this->GetVelX() > 0)
			{
				this->SetVelX(0);
				this->SetPosX((float)CGame::GetInstance()->GetWidth()-this->GetWidth());
			}
			if(this->m_pTarget->GetPosX() + m_pTarget->GetWidth() < this->GetPosX())
				this->SetVelX(-300);
			else if(this->m_pTarget->GetPosX() > this->GetPosX() + this->GetWidth())
				this->SetVelX(300);

			if(m_battack==false)
				m_fTimer+=fElapsedTime;
			if(m_fAttackTimer<=m_fTimer&&m_battack==false)
			{
				m_fTimer=0;
				m_battack=true;
			}
			if(this->GetPosY() + this->GetHeight() < CGame::GetInstance()->GetHeight() && this->OnPlatform() == false)
			{
				//check if animation is jumping. set to it
				this->SetVelY(this->GetVelY()+5);
			}
			if(this->GetPosY() + this->GetHeight() > (int)CGame::GetInstance()->GetHeight())
			{
				this->SetPosY((float)CGame::GetInstance()->GetHeight()-this->GetHeight());
			}


}

void CEnemy::Render(void)
{
	m_pAM=CAnimationManager::GetInstance();
		m_pD3D= CSGD_Direct3D::GetInstance();

	//	 collisionRect
	m_pD3D->DrawRect((m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY())),0,0,255);
	//RECT temp = {(int)GetPosX(), (int)GetPosY(),(int)GetPosX()+1, (int)GetPosY()+1};
	m_pAM->Render(m_cAniInfo,(int)GetPosX(), (int)GetPosY(),1.0,this->GetFacing());

}

bool CEnemy::Init(CEntity* pTarget,int x,int y,int speedset)
{
	m_pES = CEventSystem::GetInstance();
	m_pTM	= CSGD_TextureManager::GetInstance();
	m_pXA	= CSGD_XAudio2::GetInstance();
	m_pD3D	= CSGD_Direct3D::GetInstance();
	m_pDI	= CSGD_DirectInput::GetInstance();
	m_pXA	= CSGD_XAudio2::GetInstance();
	m_pMS	= CMessageSystem::GetInstance();
	m_pAM	= CAnimationManager::GetInstance();

	CEventSystem::GetInstance()->RegisterClient("take damage", this);
	CEventSystem::GetInstance()->RegisterClient("Return", this);
	if(pTarget->GetType() != OBJ_PLAYER)
		return false;

	//Set planned animations
	m_cAniInfo.SetName("EBaseWalk");		 //Specific to class of enemy
	m_cAniInfo.SetNext("EBaseAttack");	 //Specific to class of enemy
	m_cAniInfo.SetTime(0);			 //Specific to class of enemy
	m_cAniInfo.SetFrame(0);			 //Specific to class of enemy

	this->SetHeight(m_pAM->GetCHeight(m_cAniInfo));
	this->SetWidth(m_pAM->GetCWidth(m_cAniInfo));

	this->SetFacing(true);
	this->SetDensity(1);

	this->SetPosX(float(x));
	this->SetPosY(float(y));//(float)CGame::GetInstance()->GetHeight() - this->GetHeight()-500);
	this->m_eType = OBJ_ENEMY;
	this->SetVelX(0);
	this->SetVelY(0);
	this->m_pTarget = pTarget;
	this->m_nHealth = 100;
	this->OnPlatform(false);
	m_fTimer =0;
	m_fAttackTimer =0.75f;
	m_battack=false;



	return true;
}

bool CEnemy::CheckCollision(IEntity* pOther)
{
	m_pAM=  CAnimationManager::GetInstance();
	RECT ZERORECT ={0,0,0,0};
	if(CEntity::CheckCollision(pOther) == false)
		return false;
	if(pOther==this)
		return false;
	switch(pOther->GetType())
	{
	case OBJ_PLATFORM:
		{
			RECT collisionRect = pOther->GetRect();
			RECT Collider = m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY());
			RECT Temp = {0,0,0,0};
			if(IntersectRect(&Temp,&Collider,&collisionRect)==TRUE)
			{
				int L,T,R,B;
				L=Temp.left;T=Temp.top;R=Temp.right;B=Temp.bottom;

				if(this->GetPosY() <= collisionRect.bottom)
					this->SetVelY(this->GetVelY() + 5);
				if(this->GetPosY() >= collisionRect.top-3 )
				{
					if	(L!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.left-this->GetWidth());
					}
					if(R!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.right);
					}
				}
				if(this->GetVelY() > 0)
				{
					//if(this->GetPosY() + this->GetHeight() <= collisionRect.top + 10 && this->GetPosY() + this->GetHeight() >= collisionRect.top - 15)
					if(B!=0)
					{
						this->OnPlatform(true);
						if(this->GetVelY() > 0)
							this->SetVelY(0);	
					}	
				}
			}
		}
		break;
	case OBJ_TILE:
		{
			RECT collisionRect = pOther->GetRect();
			RECT Collider = m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY());
			RECT Temp = {0,0,0,0};
			if(IntersectRect(&Temp,&Collider,&collisionRect)==TRUE)
			{
				int L,T,R,B;
				L=Temp.left;T=Temp.top;R=Temp.right;B=Temp.bottom;
				if(this->GetPosY() <= collisionRect.bottom)
					this->SetVelY(this->GetVelY() + 5);
				if(this->GetPosY() >= collisionRect.top-3 )
				{
					if	(L!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.left-this->GetWidth());
					}
					if(R!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.right);
					}
				}
				if(this->GetVelY() > 0)
				{
					if(B!=0)
					{
						this->OnPlatform(true);
						if(this->GetVelY() > 0)
							this->SetVelY(0);	
					}	
				}
			}
		}
		break;
	case OBJ_PLAYER:
		{
			RECT collisionRect = pOther->GetRect();
			RECT Collider = m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY());
			RECT Temp = {0,0,0,0};
			if(IntersectRect(&Temp,&Collider,&collisionRect)==TRUE)
			{
				int L,T,R,B;
				L=Temp.left;T=Temp.top;R=Temp.right;B=Temp.bottom;

				if(this->GetPosY() <= collisionRect.bottom)
					this->SetVelY(this->GetVelY() + 5);

					if	(L!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.left-this->GetWidth());
						/*
						if attack cool down is up
						switch to attack animations
						if the the attack animation is on  send player damage.
						*/
						if(m_battack==true)
						{
							//call class attack animation
							m_cAniInfo.SetName("EBaseWalk");	
							m_cAniInfo.SetNext("EBaseAttack");
							m_cAniInfo.SetTime(0);
							m_cAniInfo.SetFrame(0);
						}
					}
					else if(R!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.right);
						/*
						if attack cool down is up
						switch to attack animations
						*/
						if(m_battack==true)
						{
							m_cAniInfo.SetName("EBaseAttack");	
							m_cAniInfo.SetNext("EBaseWalk");
							m_cAniInfo.SetTime(0);
							m_cAniInfo.SetFrame(0);
						}
					}

				if(this->GetVelY() > 0)
				{
					if(B!=0)
					{
						this->OnPlatform(true);

						if(this->GetVelY() > 0)
							this->SetVelY(0);	
					}	
				}
			}
		}
		break;

	case OBJ_ENEMY:
		{
			RECT collisionRect = pOther->GetRect();
			RECT Collider = m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY());
			RECT Temp = {0,0,0,0};
			if(IntersectRect(&Temp,&Collider,&collisionRect)==TRUE)
			{
				int L,T,R,B;
				L=Temp.left;T=Temp.top;R=Temp.right;B=Temp.bottom;

				if(this->GetPosY() <= collisionRect.bottom)
					this->SetVelY(this->GetVelY() + 5);
				if(this->GetPosY() >= collisionRect.top-3 )
				{
					if	(L!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.left-this->GetWidth());
					}

					if(R!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.right);
					}
				}
				if(this->GetVelY() > 0)
				{
					if(B!=0)
					{
						this->OnPlatform(true);

						if(this->GetVelY() > 0)
							this->SetVelY(0);	
					}	
				}
			}
		}
		break;
	case OBJ_FLYING_ENEMY:
		{
			RECT collisionRect = pOther->GetRect();
			RECT Collider = m_pAM->GetCRECT(this->m_cAniInfo,(int)GetPosX(),(int)GetPosY());
			RECT Temp = {0,0,0,0};
			if(IntersectRect(&Temp,&Collider,&collisionRect)==TRUE)
			{
				int L,T,R,B;
				L=Temp.left;T=Temp.top;R=Temp.right;B=Temp.bottom;

				if(this->GetPosY() <= collisionRect.bottom)
					this->SetVelY(this->GetVelY() + 5);
				if(this->GetPosY() >= collisionRect.top-3 )
				{
					if	(L!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.left-this->GetWidth());
					}

					if(R!=0)
					{
						this->SetVelX(0);
						this->SetPosX((float)collisionRect.right);
					}
				}
				if(this->GetVelY() > 0)
				{
					if(B!=0)
					{
						this->OnPlatform(true);

						if(this->GetVelY() > 0)
							this->SetVelY(0);	
					}	
				}
			}
		}
		break;
	}
	return true;
}

void CEnemy::HandleEvent(CNEvent* pEvent)
{
	if(pEvent->GetEventID() == "take damage")
	{
		this->m_nHealth -= 35;
		CPlayer* pPlayer = dynamic_cast<CPlayer*>(this->m_pTarget);
		pPlayer->SetCurrentHits(pPlayer->GetCurrentHits()+1);
		this->SetVelX(-(this->GetVelX()+10));
	}
	if(pEvent->GetEventID() == "Return")
	{
		CEventSystem* self = CEventSystem::GetInstance();
		self->SendEvent("TakePlayerDamage");
		m_cAniInfo.SetName("EBaseWalk");
		m_cAniInfo.SetNext("EBaseAttack");
		m_cAniInfo.SetTime(0);
		m_cAniInfo.SetFrame(0);
		m_battack=false;


	}

}

RECT CEnemy::GetRect( void ) const
{
	RECT collision = {(int)this->GetPosX()- (int)(GetWidth()*0.5f), (int)this->GetPosY()-int(GetHeight()*0.5f), (int)this->GetPosX()+ int(GetWidth()*0.5), (int)this->GetPosY()+int(GetHeight()*0.5f)  };
	return collision;
}